package pl.perseus.service.rach;

import java.util.Calendar;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pl.perseus.dao.IRachDao;
import pl.perseus.model.Passlist;
import pl.perseus.model.Przel;
import pl.perseus.model.Rach;
import pl.perseus.model.User;
import pl.perseus.service.exception.TransferException;
import pl.perseus.service.passlist.IPassListService;
import pl.perseus.service.przel.IPrzelService;
import pl.perseus.service.user.IUserService;

@Service
@Transactional
public class RachService implements IRachService {

	@Autowired
	IRachDao rachDao;
	
	@Autowired
	IUserService userService;
	
	@Autowired
	IPrzelService przelewService;
	
	@Autowired
	IPassListService passListService;

	@Override
	public Rach insertRach(Rach rach) {
		return rachDao.insertRach(rach);
	}

	@Override
	public Rach selectById(Long id) {
		return rachDao.selectByIdRach(id);
	}
	
	@Override
	public List<Rach> getRachsForUser(User user){
		return rachDao.getRachsForUser(user);
	}
	
	@Override
	public List<Rach> getMineRachsToTransfer(String login, Rach rach){
		User u = userService.selectUserByLogin(login);
		rach = selectById(rach.getId());
		List<Rach> mine = getRachsForUser(u);
		mine.remove(rach);
		
		return mine;
	}
	
	@Override
	public List<Rach> getAllRachsToTransferTo(User user){
		
		List<Rach> mine = getRachsForUser(userService.selectUserByLogin(user.getLogin()));
		List<Rach> all = rachDao.getAll();
		all.removeAll(mine);
		
		return all;
	}
	
	@Override
	public Rach getByIdRach(Long id){
		return rachDao.selectByIdRach(id);
	}
	
	@Override
	public void transfer(Rach out, Rach in, Long cash, String title, String receiverDetails, String confirmationCode) throws TransferException{
		out = selectById(out.getId());
		in = selectById(in.getId());
		
		if(out.getAmount() < cash || cash < 0) throw new TransferException();
		
		checkConfirmationCode(userService.getByRach(out), confirmationCode);
		
		
		przelewService.insertPrzel(getPrzel(out, in, cash, title, receiverDetails));
		
		out.setAmount(out.getAmount() - cash);
		in.setAmount(in.getAmount() + cash);
		
		rachDao.updateRach(in);
		rachDao.updateRach(out);
		
		return;
	}
	
	private void checkConfirmationCode(User u, String confirmationCode) throws TransferException{
		Passlist pass = passListService.getFirstUnusedPassListForUser(u);
		
		if(!DigestUtils.md5Hex(confirmationCode).equals(pass.getPass().trim())){
			throw new TransferException(); 
		}
		
		pass.setActive(false);
		passListService.updatePassList(pass);
		
	}
	
	private Przel getPrzel(Rach out, Rach in, Long cash, String title, String receiverDetails){
		Przel p = new Przel();
		User rachOwner = userService.getByRach(in);
		p.setAmount(cash);
		p.setDate_exec(Calendar.getInstance().getTime());
		p.setTitle1(title);
		p.setOdb_nazwa1(rachOwner.getUsername());
		p.setOdb_nazwa2(receiverDetails);
		p.setId_rach(out.getId());
		p.setRach_target(in.getId());
		
		return p;
	}
	
}
